<template>
  <view class="options-item" :class="submitStatus(item)"
    v-for="item in data.exam_option" :key="item.lable" @click="onSelect(item)">
    <view class="option-select iconfont" :class="judgeSelect(item)"></view>
    <text decode class="option-lable">{{ item.lable }}.&nbsp;&nbsp;</text>
    <rich-text class="rich-text" :nodes="item.value"></rich-text>
  </view>
</template>

<script setup>
import { inject, ref, watch } from 'vue'
import config from './config.js'

const examType = inject('sv-exam-type')

const props = defineProps({
  // 题目数据
  data: {
    type: Object,
    default: () => {}
  },
})

const emits = defineEmits(['change'])

const selected = ref(props.data.selected || []) // 未开启多选时，只保留一个元素
const correct = ref(props.data.correct) // 初始化正确与否
const isMultiple = ref(props.data.exam_type == '1')
watch(() => props.data, (newData) => {
  selected.value = newData.selected
  correct.value = newData.correct
  isMultiple.value = newData.exam_type == '1' ? true : false
})

function onSelect(e) {
  // 若已提交，则无法再进行选择
  if (props.data.submit) return

  if (isMultiple.value) {
    /**
     * 多选
     * 若selected中已包含e.lable选项，则移除，否则添加
     */
    selected.value = selected.value?.includes(e.lable) ?
      selected.value?.filter((item) => item !== e.lable) : [...selected.value, e.lable]
  } else {
    /**
     * 单选
     * 只保留最后一个元素
     */
    selected.value = [e.lable]
  }

  /**
   * 比对答案
   * 比较answer与selected中元素是否相同(不考虑顺序)
   */
  correct.value = arrEqual(props.data.exam_answer, selected.value)

  emits('change', { selected: selected.value, correct: correct.value })
}

/**
 * 比较两个简单数组中元素是否相同
 * @param {array,string} arr1
 * @param {array,string} arr2
 */
function arrEqual(arr1, arr2) {
  if (!Array.isArray(arr1)) {
    arr1 = [arr1]
  }
  if (!Array.isArray(arr2)) {
    arr2 = [arr2]
  }
  if (arr1.length !== arr2.length) return false
  return arr1.every((value) => arr2.includes(value))
}

/**
 * 计算提交结果状态
 * 若答对，则只显示正确状态，若答错，则显示正确状态和错误状态
 */
function submitStatus(item) {
  if (props.data.submit) {
    if (correct.value) {
      return props.data.exam_answer?.includes(item.lable) ? 'correct-bg' : ''
    } else {
      return props.data.exam_answer?.includes(item.lable) ? 'correct-bg' : 'wrong-bg'
    }
  } else {
    return ''
  }
}

/**
 * 标记判断
 * 背题模式：直接显示对错答案
 * 刷题模式/模拟考试：显示选择图标，注意多选和单选情况
 */
const judgeSelect = (item) => {
  if (examType.value === config.examTypeDict[0]) {
    // 背题模式
    return props.data.exam_answer?.includes(item.lable) ?
      'icon-correct primary-color' :
      'icon-wrong error-color'
  }
  if (isMultiple.value) {
    // 多选 - 刷题模式/模拟考试
    return selected.value?.includes(item.lable) ? 'icon-select primary-color' : ''
  } else {
    // 单选 - 刷题模式/模拟考试
    return selected.value && selected.value[0] === item.lable ? 'icon-select primary-color' : ''
  }
}
</script>

<style lang="scss">
@import url('./icons/iconfont.css');

.options-item {
  display: flex;
  align-items: center;
  margin-bottom: var(--paper-unit-12);
  padding: var(--paper-unit-12);
  border-radius: calc(#{var(--paper-unit-12)} / 2);
  background-color: var(--info-color);

  &.correct-bg {
    background-color: rgba(0, 216, 134, 0.6);
  }

  &.wrong-bg {
    background-color: rgba(255, 68, 79, 0.6);
  }

  .option-select {
    display: inline-block;
    width: var(--paper-unit-16);
    height: var(--paper-unit-16);
    background-color: var(--bg-color);
    border: 1px solid #{var(--border-color)};
    border-radius: 50%;
    margin-right: calc(#{var(--paper-unit-12)});
    box-sizing: content-box;
    cursor: pointer;
    flex-shrink: 0;
  }

  .option-lable {}
}

.rich-text {
  display: inline-block;
  pointer-events: none;
}

.primary-color {
  color: var(--primary-color);
}

.success-color {
  color: var(--success-color);
}

.warning-color {
  color: var(--warning-color);
}

.error-color {
  color: var(--error-color);
}

.info-color {
  color: var(--info-color);
}
</style>